package fengstyle;

import com.alibaba.fastjson.JSON;
import fengstyle.entity.Book;
import org.apache.http.HttpHost;
import org.apache.lucene.index.IndexReader;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.io.IOException;

@SpringBootApplication
public class EsDemoApplication {

    public static void main(String[] args) throws IOException {
        SpringApplication.run(EsDemoApplication.class, args);

//        createIndex();
//        getIndex();
//        insert();
//        updateBook();
//        queryDoc();
//        delDoc();
//        batchInsert();
        search();

        System.exit(0);
    }

    public static void createIndex() throws IOException{
        //创建 es 客户端
        RestHighLevelClient client = createClient();
        //创建索引
        CreateIndexRequest indexRequest = new CreateIndexRequest("createindextest");
        CreateIndexResponse response = client.indices().create(indexRequest, RequestOptions.DEFAULT);
        System.out.println("创建索引：" + response.isAcknowledged());
        closeClient(client);

        /**
         * http://localhost:9200/_cat/indices?v
         * 浏览器打开这个地址，查看索引信息，如下：
         * health status index           uuid                   pri rep docs.count docs.deleted store.size pri.store.size
         * yellow open   createindextest geWTaZ3URXKiqM69A7i-1Q   1   1          0            0       225b           225b
         */

    }

    public static void getIndex() throws IOException{
        //创建 es 客户端
        RestHighLevelClient client = createClient();

        //查询索引库
        GetIndexRequest getIndexRequest = new GetIndexRequest("createindextest");
        GetIndexResponse getIndexResponse = client.indices().get(getIndexRequest, RequestOptions.DEFAULT);
        //查询结果
        System.out.println(getIndexResponse.getAliases());
        System.out.println(getIndexResponse.getMappings());
        System.out.println(getIndexResponse.getSettings());
        closeClient(client);

        /**
         * http://localhost:9200/createindextest
         * 浏览器打开这个地址，可以查看索引信息，如下：
         * {"createindextest":{"aliases":{},"mappings":{},"settings":{"index":{"routing":{"allocation":{"include":{"_tier_preference":"data_content"}}},"number_of_shards":"1","provided_name":"createindextest","creation_date":"1663577491886","number_of_replicas":"1","uuid":"geWTaZ3URXKiqM69A7i-1Q","version":{"created":"8040099"}}}}}
         */

    }

    public static void insert() throws IOException{
        //创建 es 客户端
        RestHighLevelClient client = createClient();
        IndexRequest indexRequest = new IndexRequest();
        //插入数据
        indexRequest.index("bookindex").id("1002");
        Book book = new Book();
        book.setTitle("book-1002");
        book.setDesc("book-1002-描述");
        book.setId("1002");
        String bookJson = JSON.toJSONString(book);
        //将json数据放进request，作为数据源
        indexRequest.source(bookJson, XContentType.JSON);
        IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);
        //查看结果
        DocWriteResponse.Result result = indexResponse.getResult();
        System.out.println(indexRequest);
        System.out.println(result);
        closeClient(client);

        /**
         * http://localhost:9200/bookindex/_doc/1001
         * {"_index":"bookindex","_id":"1001","_version":1,"_seq_no":0,"_primary_term":1,"found":true,"_source":{"desc":"book-1001-描述","title":"book-1001"}}
         */

    }

    public static void updateBook() throws IOException{
        //创建 es 客户端
        RestHighLevelClient client = createClient();
        UpdateRequest updateRequest = new UpdateRequest();
        //表示对文档库的哪个索引的哪条数据进行修改
        updateRequest.index("bookindex").id("1002");
        //doc 表示文档数据
        updateRequest.doc(XContentType.JSON, "desc", "book-1002-描述-update");
        UpdateResponse updateResponse = client.update(updateRequest, RequestOptions.DEFAULT);
        System.out.println(updateResponse.getResult());
        closeClient(client);

        /**
         * http://localhost:9200/bookindex/_doc/1002
         * {"_index":"bookindex","_type":"_doc","_id":"1002","_version":2,"_seq_no":1,"_primary_term":1,"found":true,"_source":{"desc":"book-1002-描述-update","id":"1002","title":"book-1002"}}
         */
    }

    public static void queryDoc() throws IOException{
        RestHighLevelClient client = createClient();
        GetRequest getRequest = new GetRequest();
        //查询条件：查询的索引库和数据id
        getRequest.index("bookindex").id("1002");
        GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
        System.out.println(getResponse.getSourceAsString());
        closeClient(client);

        /**
         * {"desc":"book-1002-描述-update","id":"1002","title":"book-1002"}
         */
    }

    public static void delDoc() throws IOException{
        RestHighLevelClient client = createClient();
        DeleteRequest request = new DeleteRequest();
        //要删除的索引库和数据id
        request.index("bookindex").id("1002");
        DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
        System.out.println(response.getResult());
        System.out.println(request.toString());
        closeClient(client);

        /**
         * DELETED
         * delete {[bookindex][_doc][1002]}
         */
    }

    public static void batchInsert() throws IOException{
        RestHighLevelClient client = createClient();
        //批量请求
        BulkRequest bulkRequest = new BulkRequest();
        IndexRequest indexRequest = null;
        for (int i = 0; i < 5; i++) {
            indexRequest = new IndexRequest();
            indexRequest.index("batch-book").id("book-100" + i);
            Book book = new Book();
            book.setId("100" + i);
            book.setTitle("book-title-100" + i);
            book.setDesc("book-desc-100" + i);
            indexRequest.source(JSON.toJSONString(book), XContentType.JSON);
            bulkRequest.add(indexRequest);
        }
        System.out.println("es批量插入数据数量：" + bulkRequest.numberOfActions());
        //设置索引刷新规则
        bulkRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
        BulkResponse response = client.bulk(bulkRequest, RequestOptions.DEFAULT);
        System.out.println("es插入数据失败：" + response.hasFailures());
        System.out.println("es插入数据结果：" + JSON.toJSONString(response));
        closeClient(client);
    }

    public static void search() throws IOException{
        //https://www.cnblogs.com/wyw123456/articles/15834913.html
        RestHighLevelClient client = createClient();
        //搜索请求
        SearchRequest searchRequest = new SearchRequest();
        //指定索引
        searchRequest.indices("batch-book");
        //指定搜索条件
        SearchSourceBuilder builder = new SearchSourceBuilder();
        //构建搜索条件
        builder.query(QueryBuilders.matchQuery("title", "1000"));
        searchRequest.source(builder);
        System.out.println("搜索条件：" + JSON.toJSONString(searchRequest));
        //执行搜索
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        System.out.println("搜索结果：" + JSON.toJSONString(response));
        //获取数据
        SearchHits hits = response.getHits();
        System.out.println(JSON.toJSONString(hits));
        //获取详细数据
        SearchHit [] searchHits = hits.getHits();
        for (SearchHit hit : searchHits){
            System.out.println(hit.getSourceAsString());
        }
        closeClient(client);

        /**
         * 搜索条件：{"batchedReduceSize":512,"ccsMinimizeRoundtrips":true,"description":"","maxConcurrentShardRequests":5,"parentTask":{"id":-1,"nodeId":"","set":false},"preFilterShardSize":128,"shouldStoreResult":false,"suggestOnly":false}
         * 搜索结果：{"clusters":{"fragment":true,"skipped":0,"successful":0,"total":0},"failedShards":0,"fragment":false,"hits":{"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{},"id":"book-1000","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.3862942,"seqNo":-2,"sortValues":[],"sourceAsMap":{"id":"1000","title":"book-title-1000","desc":"book-desc-1000"},"sourceAsString":"{\"desc\":\"book-desc-1000\",\"id\":\"1000\",\"title\":\"book-title-1000\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":1.3862942,"totalHits":{"relation":"EQUAL_TO","value":1}},"numReducePhases":1,"profileResults":{},"shardFailures":[],"skippedShards":0,"successfulShards":1,"timedOut":false,"took":{"days":0,"daysFrac":2.3148148148148148E-8,"hours":0,"hoursFrac":5.555555555555555E-7,"micros":2000,"microsFrac":2000.0,"millis":2,"millisFrac":2.0,"minutes":0,"minutesFrac":3.3333333333333335E-5,"nanos":2000000,"seconds":0,"secondsFrac":0.002,"stringRep":"2ms"},"totalShards":1}
         * {"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{},"id":"book-1000","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.3862942,"seqNo":-2,"sortValues":[],"sourceAsMap":{"id":"1000","title":"book-title-1000","desc":"book-desc-1000"},"sourceAsString":"{\"desc\":\"book-desc-1000\",\"id\":\"1000\",\"title\":\"book-title-1000\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":1.3862942,"totalHits":{"relation":"EQUAL_TO","value":1}}
         * {"desc":"book-desc-1000","id":"1000","title":"book-title-1000"}
         */

    }

    public static RestHighLevelClient createClient(){
        //创建 es 客户端
        RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http")));
        return client;
    }

    public static void closeClient(RestHighLevelClient client) throws IOException {
        client.close();
    }

}
